<?php
namespace Forxx;

use Lavender\Dao\RedisTable as RTable;
use Lavender\Core;

abstract class RedisTable extends RTable
{

	// update String
	public function update($id, $data, $time = null)
	{
		$key = $this->makeKey($id);
		$json_value = $this->pack($data);
		$this->get_handle()->set($key, $json_value, $time);
	}

	
	public function delete($id, $field = null, $type = null)
	{
		$key = $this->makeKey($id);
		if(empty($type)) {
			$this->get_handle()->del($key);
		}else{
			switch ($type) {
				case 'H': // hash表删除
					return $this->get_handle()->hdel($key, $field);
				//请根据自己的需求扩展
			}
		}
	}

	public function is_exists($id = '', $field = null, $type = null)
	{
		$key = $this->makeKey($id);
		if(empty($type)) {
			return $this->get_handle()->exists($key);
		}else{
			switch ($type) {
				case 'H': // hash表检测
					return $this->get_handle()->hexists($key, $field);
				//请根据自己的需求扩展
			}
		}

		return false;
	}

	/**
	 * 队列入队
	 * 返回队列长度
	 */
	public function enqueue($id,$value)
	{
		$key = $this->makeKey($id);
		$value = $this->pack($value);
		return  $this->get_handle()->RPUSH($key,$value);
	}

	/**
	 * 队列出队
	 * 返回出队值
	 */
	public function dequeue($id)
	{
		$key = $this->makeKey($id);
		$value = $this->get_handle()->LPOP($key);
		return $this->unpack($value,true);
	}

	//  队列长度
	public function queue_length($id)
	{
		$key = $this->makeKey($id);
		return $this->get_handle()->LRANGE($key,0,-1);
	}

	/**
	 * list类型 左入栈
	 * 
	 * @param $id
	 * @param $value
	 */
	public function lpush($id, $value)
	{
		$key = $this->prefix;
		if(!is_null($id)){
			$key = $this->makeKey($id);
		}
		if(is_array($value)){
			foreach ($value as $v) {
				$this->get_handle()->lpush($key, $v);
			}	
		}else{
			$this->get_handle()->lpush($key, $value);
		}
		
	}
		
	
	/**
	 * list类型 左入栈
	 *
	 * @param $id
	 * @param array $value
	 */
	public function lpushx($id, array $value)
	{
		if(empty($id)){
			throw new \Exception('id is empty',ErrnoPlus::PARAM_LOSE);
		}
		$key = $this->makeKey($id);
		foreach ($value as $v) {
			$this->get_handle()->lpush($key, $v);
		}
	}
	
	/**
	 * 返回名称为key的list有多少个元素
	 */
	public function lsize($id)
	{
		if(empty($id)){
			throw new \Exception('id is empty',ErrnoPlus::PARAM_LOSE);
		}
		$key = $this->makeKey($id);
		return $this->get_handle()->lSize($key);
	}

	/**
	 * list类型，删除链表类指定的值，返回实际被删除的数量。
	 */
	public function lrem($id, $value, $num = 1)
	{
		$key = $this->prefix;
		if(!is_null($id)){
			$key = $this->makeKey($id);
		}
		return $this->get_handle()->lrem($key, $value, $num);
	}

	//list类型 从左至右统计
	public function lrange($id, $offset, $length)
	{
		$key = $this->prefix;
		if(!is_null($id)){
			$key = $this->makeKey($id);
		}
		
		return $this->get_handle()->lrange($key, $offset, $length);
	}
	
	public function ltrim($id, $star, $end)
	{
		$key = $this->prefix;
		if(!is_null($id)){
			$key = $this->makeKey($id);
		}
		if(!is_numeric($star) || !is_numeric($end)){
			throw new \Exception('star or end not number',ErrnoPlus::PARAM_LOSE);
		}
		return $this->get_handle()->ltrim($key, $star, $end);
	}

	/**
	 * Hmset
	 * 
	 * @param $key
	 * @param $arr
	 */
	public function hmset($key, array $arr)
	{
		$key = $this->prefix.$key;
		$fileds = array();
		
		foreach ($arr as $k => $v) {
			$fileds[$k] = $this->pack($v);
		}
		
		return $this->get_handle()->hmset($key, $fileds);
	}

	/**
	 * Hmget
	 * 
	 * @param $key
	 * @param array $fields
	 * @return mixed
	 */
	public function hmget($key, array $fields)
	{
		$key = $this->prefix.$key;
		
		$res = $this->get_handle()->hmget($key, $fields);
		$result = array();
		
		foreach ($res as $k => $v) {
			$result[$k] = $this->unpack($v);
		}
		
		return $result;
	}
	
	/**
	 * Hset
	 * 
	 * @param $key 键
	 * @param $field 字段
	 * @param $data 值
	 */
	public function hset($key,$field,$data)
	{
		if(empty($key) || empty($field)){
			throw new \Exception('param is empty',ErrnoPlus::PARAM_LOSE);
		}
		
		if(is_null($data)){
			throw new \Exception('value is null',ErrnoPlus::PARAM_INVALID);
		}
		
		$key = $this->prefix.$key;
		return $this->get_handle()->hSet($key,$field,$this->pack($data));
	}
	
	/**
	 * Hget
	 * 
	 * @param $key 键
	 * @param $field 字段
	 */
	public function hget($key,$field)
	{
		
		if(empty($key) || empty($field)){
			throw new \Exception('param is empty',ErrnoPlus::PARAM_LOSE);
		}
		
		$key = $this->prefix.$key;
		return $this->unpack($this->get_handle()->hGet($key,$field));
	}

	
}